# -*- coding: utf-8 -*-

#Descrição: Classe para efectuar as operações na BD SQLITE
#Data: 25/11/11
#Autor: Luís Costa Nº 6032
#-----------------------------------------------

#Para efectuar as operações na BD SQLite
import sqlite3

#Para conseguir percorrer duas listas ao mesmo tempo com um iterator
import itertools

class DataBase:
    
    #Nome da base de dados a utilizar
    #------------------
    DATASOURCE = 'rebides.db'
    
    #Ano que está atualmente a tratar
    #-----------------
    ano = ''

    def create_tables(self):
        
        #Estabelece uma ligação à BD e abre um cursor
        #-----------------------
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()
        
        #Cria a tabela de tipos de graus
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Tipos_Graus 
                          (Cod_Tipo_Grau INTEGER PRIMARY KEY AUTOINCREMENT,
                            Designacao TEXT)        
                        """)

        #Cria a tabela de graus
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Graus 
                          (Cod_Grau INTEGER PRIMARY KEY AUTOINCREMENT,
                            Cod_Tipo_Grau INTEGER,
                            Designacao TEXT)
                       """)

        #Cria a tabela de Cursos
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Cursos
                          (Cod_Curso INTEGER PRIMARY KEY AUTOINCREMENT,
                            Designacao TEXT)
                       """)

        #Cria a tabela de Categorias
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Categorias
                          (Cod_Categoria INTEGER PRIMARY KEY AUTOINCREMENT,
                            Designacao TEXT)
                       """)

        #Cria a tabela de Regimes
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Regimes
                          (Cod_Regime INTEGER PRIMARY KEY AUTOINCREMENT,
                            Designacao TEXT)
                       """)

        #Cria a tabela de Estabelecimentos
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Estabelecimentos
                          (Cod_Estabelecimento INTEGER PRIMARY KEY AUTOINCREMENT, 
                            Designacao TEXT)
                       """)

        #Cria a tabela de Tipos de Estabelecimento
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Tipos_Estabelecimento
                          (Cod_Tipo_Estabelecimento INTEGER PRIMARY KEY,
                            Designacao TEXT)
                       """)

        #Cria a tabela de Docentes
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Docentes
                          (Cod_Docente INTEGER PRIMARY KEY,
                            Nome_Completo TEXT)
                       """)
       
        #Cria a tabela de Fichas de Docencia
        #-----------------------
        cursor.execute("""CREATE TABLE IF NOT EXISTS Fichas_Docencia
                          (Cod_Fichas_Docencia INTEGER PRIMARY KEY AUTOINCREMENT, 
                           Ano INTEGER,
                           Cod_Docente INTEGER,
                           Cod_Estabelecimento INTEGER,
                           Cod_Categoria INTEGER,
                           Cod_Regime INTEGER,
                           Cod_Tipo_Estabelecimento INTEGER,
                           Cod_Curso INTEGER,
                           Cod_Grau INTEGER)
                       """)        
        cursor.close()

        print ("Tabelas criádas com sucesso!")

        #Processa os dados para a tabela de tipos de graus
        #---------------
        print 'A processar os tipos de graus...'
        self.process_tipos_graus()
        print 'Tipos de graus processados com sucesso!'
    pass
    
    #Recebe um dicionario com os dados de um ficheiro CSV.
    #Processa os dados recebidos em atualiza a base de dados.
    #--------------------------
    def process_data(self, dictData, ano):
        
        #Guarda o ano que está a ser tratado
        #Formata o ano que foi passado
        if ano < 10:
            ano = '0' + str(ano)

        else:
            ano = str(ano)
        pass

        self.ano = '20' + ano
        
        #Inicia o processamento dos dados para a as tabela auxiliares
        #-------------------------------------------
        print 'A iniciar o processamento dos dados para as tabelas auxiliares'
        print '---------------'
        
        #Processa os dados para a tabela Docentes
        #----------------
        print 'A processar os docentes...'
        self.process_docentes(dictData['Cod_Docente'], dictData['Nome'])
        print 'A docentes processados com sucesso!'
        
        #Processa os dados para a tabela Categorias
        #----------------
        print 'A processar as categorias...'
        self.process_categorias(dictData['Categoria'])
        print 'Categorias processadas com sucesso!\n'
        #-------------------------------------------

        #Processa os dados para a tabela Cursos
        #----------------
        print 'A processar os cursos...'
        self.process_cursos(dictData['Curso'])
        print 'Cursos processados com sucesso!\n'
        #-------------------------------------------
        
        #Processa os dados para a tabela Estabelecimentos
        #----------------
        print 'A processar os estabelecimentos...'
        self.process_estabelecimentos(dictData['Nome_Estab'])
        print 'Estabelecimentos processados com sucesso!\n'
        #-------------------------------------------

        #Processa os dados para a tabela Graus
        #----------------
        print 'A processar os graus...'
        self.process_graus(dictData['Ultimo_Grau'])
        print 'Graus processados com sucesso!\n'
        #-------------------------------------------

        #Processa os dados para a tabela Regimes
        #----------------
        print 'A processar os regimes...'
        self.process_regimes(dictData['Regime_Tempo'])
        print 'Regimes processados com sucesso!\n'
        #-------------------------------------------

        #Processa os dados para a tabela Tipos_Estabelecimento
        #----------------
        print 'A processar os tipos de estabelecimento...'
        self.process_tipos_estabelecimento(dictData['Tipo_Estab'])
        print 'Tipos de estabelecimento processados com sucesso!\n'
        #-------------------------------------------
        
        #Processa os dados para a tabela Fichas_Docencia
        #----------------
        print 'A processar as fichas de docência...'
        self.process_fichas_docencia(dictData)
        print 'Fichas de docência processadas com sucesso!\n'
        #-------------------------------------------
    pass
    
    #Processa os dados para a tabela de tipos de graus
    #----------------------------------------
    def process_tipos_graus(self):
        
        tiposGraus = ['Doutoramento', 'Mestrado', 'Licenciatura', 'Outro']
        try:
            #Abre uma ligação à BD e um cursor
            #-------------------- 
            bd = sqlite3.connect(self.DATASOURCE)
            cursor = bd.cursor()
            
            #Limpa a tabela
            #-----------------
            cmd ="""DELETE FROM Tipos_Graus"""
            
            cursor.execute(cmd)
            bd.commit()

            #Insere os registos da lista na BD
            #-------------------
            for tipo in tiposGraus:

                cmd ="""INSERT INTO Tipos_Graus
                        (Designacao)
                    VALUES
                        (
                        '{0}'
                        )""".\
                    format(tipo)
            
                cursor.execute(cmd)
            pass
            
            bd.commit()
            cursor.close()

            print "Tipos de graus inseridos com sucesso!"

        except Exception, e:
            print "Erro ao inserir os tipos de graus: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #Processa os dados para a tabela de Docentes.
    #Recebe duas listas com os campos e vai verificar quais é que não estão
    #na tabela Docentes e atualiza a tabela.
    #-----------------------------------------
    def process_docentes(self, codDocentes, nomeDocentes):
        
        #Remove os duplicados
        #------------------------
        newDocentes = [codDocentes, nomeDocentes]
        newDocentes = self.remove_duplicated_docentes_from_CSV(newDocentes)

        #Trata os nomes dos docentes para retirar os apostrofos
        newDocentes[1] = self.clear_apostrophe(newDocentes[1])

        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Verifica se a BD tem registos
        #-------------------
        cmd ="""SELECT     COUNT(*)
                FROM       Docentes"""

        cursor.execute(cmd)
        row = cursor.fetchone()
        rowCount = row[0]
        
        print "Total de docentes na BD: " +str(rowCount)

        #Verifica se a tabela está vazia. Se estiver insere todos os campos
        #sem efetuar o teste para ver se já existem na BD
        #---------------------
        docentesInseridos = 0

        try:
            if rowCount > 0:
                
                print "A ler os docentes da BD..."
                
                #Vai buscar os dados que estão na tabela docentes
                cmd ="""SELECT     *
                        FROM       Docentes
                        ORDER BY   Cod_Docente"""

                cursor.execute(cmd)
                
                bdData = [[],[]]
                
                #Coloca os Códigos dos docentes da BD num set
                #------------------
                for row in cursor:
                    bdData[0].append(str(row[0]))
                    bdData[1].append(row[1].encode("utf-8"))
                pass
                
                #Remove os duplicados. Deste modo os docentes que já estão
                #na BD não serão inseridos
                #-----------------------
                newDocentes = self.remove_duplicated_docentes_from_bd(newDocentes, bdData)
                
                #Insere os novos docentes na BD
                #-------------------
                for codDocente, NomeDocente in itertools.izip(newDocentes[0], 
                    newDocentes[1]):
                    
                    cmd = """INSERT INTO Docentes
                                    (
                                    Cod_Docente,
                                    Nome_Completo) 
                                VALUES 
                                    (
                                    {0},
                                    '{1}'
                                    )""".\
                            format(codDocente, 
                                NomeDocente)
                    cursor.execute(cmd)
                    docentesInseridos = docentesInseridos + 1
                pass
                
            else:
                
                #Insere a lista completa na bd
                #------------------
                for codDocente, NomeDocente in itertools.izip(newDocentes[0], 
                    newDocentes[1]):
                    
                    cmd = """INSERT INTO Docentes
                                    (
                                    Cod_Docente,
                                    Nome_Completo) 
                                VALUES 
                                    (
                                    {0},
                                    '{1}'
                                    )""".\
                            format(codDocente, 
                                NomeDocente)
                    cursor.execute(cmd)
                    docentesInseridos = docentesInseridos + 1
                pass
            pass
        
            bd.commit()
            cursor.close()

            print "Total de docentes inseridos na BD: " + str(docentesInseridos)

        except Exception, e:
            print "Erro ao inserir os Docentes: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #-----------------------------------------
    
    #Remove os docentes duplicados.
    #Verifica se os docentes já existem noutra lista.
    #Se não existirem adiciona. No fim devolve uma lista com os adicionados.
    #-------------------------
    def remove_duplicated_docentes_from_CSV(self, newDocentes):
        
        print "A remover os docentes duplicados do CSV..."

        docentes = [[],[]]
               
        for n in range(len(newDocentes[0])):

            if newDocentes[0][n] not in(docentes[0]):

                #Adiciona os docentes à lista a devolver
                docentes[0].append(newDocentes[0][n])
                docentes[1].append(newDocentes[1][n])
            pass
        pass
        
        print "Total de docentes iniciais: " + str(len(newDocentes[0]))
        print "Total de docentes atuais: " + str(len(docentes[0]))

        return docentes
    pass
    #-----------------------------------------

    #Remove os docentes duplicados.
    #Verifica se os docentes já existem noutra lista.
    #Se não existirem adiciona. No fim devolve uma lista com os adicionados.
    #-------------------------
    def remove_duplicated_docentes_from_bd(self, newDocentes, oldDocentes):
        
        print "A remover os docentes duplicados da BD..."

        docentes = [[],[]]
               
        for n in range(len(newDocentes[0])):

            if newDocentes[0][n] not in(oldDocentes[0]):
                
                #Adiciona os docentes à lista a devolver
                docentes[0].append(newDocentes[0][n])
                docentes[1].append(newDocentes[1][n])
                                
            pass
        pass
        
        print "Total de docentes iniciais: " + str(len(newDocentes[0]))
        print "Total de docentes atuais: " + str(len(docentes[0]))

        return docentes
    pass
    #-----------------------------------------

    #Processa os dados para a tabela de Categorias.
    #Recebe os dados e vai verificar quais é que não estão
    #na tabela Categorias e atualiza a tabela.
    #-----------------------------------------
    def process_categorias(self, categorias):

        #Remove as categorias duplicadas
        #---------------------
        categorias = set(categorias)
        
        #Trata os nomes das categorias para retirar os apostrofos
        categorias = set(self.clear_apostrophe(categorias))
        
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Verifica se a BD tem registos
        #-------------------
        cmd ="""SELECT     Designacao
                FROM       Categorias"""
                
        cursor.execute(cmd)
                
        bdData = set()
        
        #Coloca as categorias da BD num set
        #------------------
        for row in cursor:
            bdData.add(row[0].encode('utf-8'))
        pass

        #Faz a diferença dos sets de modo a só ficar com os novos registos
        #-------------
        newCategorias = categorias - bdData

        #Insere os novos registos na BD
        #--------------------
        categoriasInseridas = 0
        try:
            for categoria in newCategorias:

                cmd = """INSERT INTO Categorias
                                (
                                Designacao) 
                            VALUES 
                                (
                                '{0}')""".\
                        format(categoria)
                cursor.execute(cmd)
                categoriasInseridas = categoriasInseridas + 1
            pass
            
            bd.commit()
            cursor.close()

            print "Total de categorias inseridas na BD: " + str(categoriasInseridas)

        except Exception, e:
            print "Erro ao inserir as Categorias: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #-----------------------------------------

    #Processa os dados para a tabela de Cursos.
    #Recebe os dados e vai verificar quais é que não estão
    #na tabela Cursos e atualiza a tabela.
    #-----------------------------------------
    def process_cursos(self, cursos):

        #Remove os cursos duplicados
        #---------------------
        cursos = set(cursos)
        
        #Trata os nomes das cursos para retirar os apostrofos
        cursos = set(self.clear_apostrophe(cursos))
        
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Verifica se a BD tem registos
        #-------------------
        cmd ="""SELECT     Designacao
                FROM       Cursos"""
                
        cursor.execute(cmd)
                
        bdData = set()
        
        #Coloca os cursos da BD num set
        #------------------
        for row in cursor:
            bdData.add(row[0].encode('utf-8'))
        pass

        #Faz a diferença dos sets de modo a só ficar com os novos registos
        #-------------
        newCursos = cursos - bdData

        #Insere os novos registos na BD
        #--------------------
        cursosInseridos = 0
        try:
            for curso in newCursos:

                cmd = """INSERT INTO Cursos
                                (
                                Designacao) 
                            VALUES 
                                (
                                '{0}')""".\
                        format(curso)
                cursor.execute(cmd)
                cursosInseridos = cursosInseridos + 1
            pass
            
            bd.commit()
            cursor.close()

            print "Total de cursos inseridos na BD: " + str(cursosInseridos)

        except Exception, e:
            print "Erro ao inserir os Cursos: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #-----------------------------------------

    #Processa os dados para a tabela de Estabelecimentos.
    #Recebe os dados e vai verificar quais é que não estão
    #na tabela Estabelecimentos e atualiza a tabela.
    #-----------------------------------------
    def process_estabelecimentos(self, estabelecimentos):

        #Remove os estabelecimentos duplicados
        #---------------------
        estabelecimentos = set(estabelecimentos)
        
        #Trata os nomes dos estabelecimentos para retirar os apostrofos
        estabelecimentos = set(self.clear_apostrophe(estabelecimentos))
        
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Verifica se a BD tem registos
        #-------------------
        cmd ="""SELECT     Designacao
                FROM       Estabelecimentos"""
                
        cursor.execute(cmd)
                
        bdData = set()
        
        #Coloca os cursos da BD num set
        #------------------
        for row in cursor:
            bdData.add(row[0].encode('utf-8'))
        pass

        #Faz a diferença dos sets de modo a só ficar com os novos registos
        #-------------
        newEstabelecimentos = estabelecimentos - bdData

        #Insere os novos registos na BD
        #--------------------
        estabelecimentosInseridos = 0
        try:
            for estabelecimento in newEstabelecimentos:

                cmd = """INSERT INTO Estabelecimentos
                                (
                                Designacao) 
                            VALUES 
                                (
                                '{0}')""".\
                        format(estabelecimento)
                cursor.execute(cmd)
                estabelecimentosInseridos = estabelecimentosInseridos + 1
            pass
            
            bd.commit()
            cursor.close()

            print "Total de estabelecimentos inseridos na BD: " + str(estabelecimentosInseridos)

        except Exception, e:
            print "Erro ao inserir os Estabelecimentos: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #-----------------------------------------

    #Processa os dados para a tabela de Graus.
    #Recebe os dados e vai verificar quais é que não estão
    #na tabela Graus. e atualiza a tabela.
    #-----------------------------------------
    def process_graus(self, graus):

        #Remove os graus duplicados
        #---------------------
        graus = set(graus)
        
        #Trata os nomes dos graus para retirar os apostrofos
        graus = set(self.clear_apostrophe(graus))
        
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Verifica se a BD tem registos
        #-------------------
        cmd ="""SELECT     Designacao
                FROM       Graus"""
                
        cursor.execute(cmd)
                
        bdData = set()
        
        #Coloca os graus da BD num set
        #------------------
        for row in cursor:
            bdData.add(row[0].encode('utf-8'))
        pass

        #Faz a diferença dos sets de modo a só ficar com os novos registos
        #-------------
        newGraus = graus - bdData

        #Insere os novos registos na BD
        #--------------------
        grausInseridos = 0
        try:
            for grau in newGraus:
                
                #Classifica o grau quanto ao tipo
                #----------------
                codTipoGrau = 4
                
                #Doutoramento
                listaPalavrasChave =['doutoramento', 'doctor', \
                                        'docteur', 'doctoris', 'doktor', \
                                        'doutorado', 'doutorada']
                
                #Verifica se o nome do grau contem alguma das palavras
                #da lista
                #------------------
                for palavraChave in listaPalavrasChave:
                    
                    if palavraChave in grau.lower():
                        codTipoGrau = 1
                        break
                pass
                
                #Verifica se o grau se enquadra no próximo tipo apenas
                #se ainda não estiver classificado
                #--------------------
                if codTipoGrau == 4:

                    #Mestrado
                    listaPalavrasChave =['mestrado', 'mestre', \
                                        'master']
                    
                    #Verifica se o nome do grau contem alguma das palavras
                    #da lista
                    #------------------
                    for palavraChave in listaPalavrasChave:
                        
                        if palavraChave in grau.lower():
                            codTipoGrau = 2
                            break
                    pass
                pass
                
                #Verifica se o grau se enquadra no próximo tipo apenas
                #se ainda não estiver classificado
                #--------------------
                if codTipoGrau == 4:

                    #Licenciatura
                    listaPalavrasChave =['licenciatura', 'curso superior', \
                                        'licenciado', 'estudos superiores']
                    
                    #Verifica se o nome do grau contem alguma das palavras
                    #da lista
                    #------------------
                    for palavraChave in listaPalavrasChave:
                        
                        if palavraChave in grau.lower():
                            codTipoGrau = 3
                            break
                    pass
                pass
                

                cmd = """INSERT INTO Graus
                                (
                                Cod_Tipo_Grau,
                                Designacao) 
                            VALUES 
                                (
                                {0}, '{1}')""".\
                        format(codTipoGrau, grau)
                cursor.execute(cmd)
                grausInseridos = grausInseridos + 1
            pass
            
            bd.commit()
            cursor.close()

            print "Total de graus inseridos na BD: " + str(grausInseridos)

        except Exception, e:
            print "Erro ao inserir os graus: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #-----------------------------------------

    #Processa os dados para a tabela de Regimes.
    #Recebe os dados e vai verificar quais é que não estão
    #na tabela Regimes e atualiza a tabela.
    #-----------------------------------------
    def process_regimes(self, regimes):

        #Remove os regimes duplicados
        #---------------------
        regimes = set(regimes)
        
        #Trata os nomes dos graus para retirar os apostrofos
        regimes = set(self.clear_apostrophe(regimes))
        
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Verifica se a BD tem registos
        #-------------------
        cmd ="""SELECT     Designacao
                FROM       Regimes"""
                
        cursor.execute(cmd)
                
        bdData = set()
        
        #Coloca os graus da BD num set
        #------------------
        for row in cursor:
            bdData.add(row[0].encode('utf-8'))
        pass

        #Faz a diferença dos sets de modo a só ficar com os novos registos
        #-------------
        newRegimes = regimes - bdData

        #Insere os novos registos na BD
        #--------------------
        regimesInseridos = 0
        try:
            for regime in newRegimes:

                cmd = """INSERT INTO Regimes
                                (
                                Designacao) 
                            VALUES 
                                (
                                '{0}')""".\
                        format(regime)
                cursor.execute(cmd)
                regimesInseridos = regimesInseridos + 1
            pass
            
            bd.commit()
            cursor.close()

            print "Total de regimes inseridos na BD: " + str(regimesInseridos)

        except Exception, e:
            print "Erro ao inserir os Regimes: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #-----------------------------------------

    #Processa os dados para a tabela de Tipos de Estabelecimento.
    #Recebe os dados e vai verificar quais é que não estão
    #na tabela Tipos_Estabelecimento e atualiza a tabela.
    #-----------------------------------------
    def process_tipos_estabelecimento(self, tiposEstabelecimento):

        #Remove os tipos_estabelecimento duplicados
        #---------------------
        tiposEstabelecimento = set(tiposEstabelecimento)
        
        #Trata os nomes dos tipos_estabelecimento para retirar os apostrofos
        tiposEstabelecimento = set(self.clear_apostrophe(tiposEstabelecimento))
        
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Verifica se a BD tem registos
        #-------------------
        cmd ="""SELECT     Designacao
                FROM       Tipos_Estabelecimento"""
                
        cursor.execute(cmd)
                
        bdData = set()
        
        #Coloca os graus da BD num set
        #------------------
        for row in cursor:
            bdData.add(row[0].encode('utf-8'))
        pass

        #Faz a diferença dos sets de modo a só ficar com os novos registos
        #-------------
        newTiposEstabelecimento = tiposEstabelecimento - bdData

        #Insere os novos registos na BD
        #--------------------
        tiposEstabInseridos = 0
        try:
            for estab in newTiposEstabelecimento:

                cmd = """INSERT INTO Tipos_Estabelecimento
                                (
                                Designacao) 
                            VALUES 
                                (
                                '{0}')""".\
                        format(estab)
                cursor.execute(cmd)
                tiposEstabInseridos = tiposEstabInseridos + 1
            pass
            
            bd.commit()
            cursor.close()

            print "Total de Tipos de Estabelecimento inseridos na BD: " + \
                    str(tiposEstabInseridos)

        except Exception, e:
            print "Erro ao inserir os Tipos de Estabelecimento: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
    pass
    #-----------------------------------------

    #Processa os dados para a tabela de Fichas de Docência.
    #Esta é a tabela principal que relaciona todas as outras.
    #Cria vários dicionários de modo ir buscar as chaves de cada registos
    #de modo a só inserir as chaves.
    #-----------------------------------------
    def process_fichas_docencia(self, dictData):
        
        #Cria uma lista para os dicionarios com os dados de cada tabela da BD
        #----------------------------------------
        dictBDDados = []
        
##        #Dicionário para a tabela de docentes
##        #-------------------
##        dictDocentes[dictData['Cod_Docente']] = dictData['Nome']
##        dictBDDados.append(dictDocentes)
        
        #Dicionário para a tabela de Categorias
        #--------------
        print 'A criar o dicionario para a tabela de Categorias'

        dictBDDados.append(self.table_to_dict('Categorias', 
                            'Cod_Categoria', 'Designacao'))

        print 'Dicionário criádo com sucesso!\n'

        #Dicionário para a tabela de Cursos
        #--------------
        print 'A criar o dicionario para a tabela de Cursos..'

        dictBDDados.append(self.table_to_dict('Cursos', 
                            'Cod_Curso', 'Designacao'))
        
        print 'Dicionário criádo com sucesso!\n'

        #Dicionário para a tabela de Estabelecimentos
        #--------------
        print 'A criar o dicionario para a tabela de Estabelecimentos..'

        dictBDDados.append(self.table_to_dict('Estabelecimentos', 
                            'Cod_Estabelecimento', 'Designacao'))

        print 'Dicionário criádo com sucesso!\n'

        #Dicionário para a tabela de Graus
        #--------------
        print 'A criar o dicionario para a tabela de Graus..'

        dictBDDados.append(self.table_to_dict('Graus', 
                            'Cod_Grau', 'Designacao'))

        print 'Dicionário criádo com sucesso!\n'

        #Dicionário para a tabela de Regimes
        #--------------
        print 'A criar o dicionario para a tabela de Regimes..'

        dictBDDados.append(self.table_to_dict('Regimes', 
                            'Cod_Regime', 'Designacao'))

        print 'Dicionário criádo com sucesso!\n'

        #Dicionário para a tabela de Tipos de Estabelecimento
        #--------------
        print 'A criar o dicionario para a tabela de Tipos de Estabelecimento..'

        dictBDDados.append(self.table_to_dict('Tipos_Estabelecimento', 
                            'Cod_Tipo_Estabelecimento', 'Designacao'))

        print 'Dicionário criádo com sucesso!\n'
        #----------------------------------------
        
        #Limpa os dados do ano que esá a inserir da tabela
        #------------------

        try:
            #Abre uma ligação à BD e um cursor
            #-------------------- 
            bd = sqlite3.connect(self.DATASOURCE)
            cursor = bd.cursor()
            
            #Limpa os dados da tabela
            #-------------------

            cmd ="""DELETE      
                    FROM        Fichas_Docencia 
                    WHERE Ano = {0}""".\
                        format(self.ano)
                        
            cursor.execute(cmd)
            bd.commit()

            #Insere na BD os dados 
            #-----------------------
            for codDocente, estabelecimento, categoria, regime, \
                tipo_estabelecimento, grau, curso in itertools.izip( \
                dictData["Cod_Docente"], dictData["Nome_Estab"], \
                dictData["Categoria"], dictData["Regime_Tempo"], \
                dictData["Tipo_Estab"], dictData["Ultimo_Grau"], \
                dictData["Curso"]):

                cmd = """INSERT INTO Fichas_Docencia
                                (
                                Ano,
                                Cod_Docente,
                                Cod_Estabelecimento,
                                Cod_Categoria,
                                Cod_Regime,
                                Cod_Tipo_Estabelecimento,
                                Cod_Grau,
                                Cod_Curso
                                ) 
                            VALUES 
                                (
                                {0},{1},{2},{3},{4},{5},{6},{7})""".\
                        format(self.ano, codDocente, \
                                dictBDDados[2][estabelecimento], \
                                dictBDDados[0][categoria], \
                                dictBDDados[4][regime], \
                                dictBDDados[5][tipo_estabelecimento], \
                                dictBDDados[3][grau], \
                                dictBDDados[1][curso])
                        
                cursor.execute(cmd)
            pass

            bd.commit()
            cursor.close()
        except Exception, e:

            print "Erro ao inserir as Fichas de Docência: \n", cmd
            print "ERRO: " + str(e)
            cursor.close()
        pass
        
    pass
    
    #Devolve um dicionario com os dados para a estatistica dos 
    #professores por estabelecimento e por ano.
    #O dicionário devolvido é composto por:
    # - Um dic. com os anos como chave;
    # - Dentro de cada ano um dic. com os nomes dos estabelecimentos
    #   como chave;
    # - Dentro do dic. de estabelecimentos um dic.com os cód. dos docentes
    #   como chave e o nome no valor.
    #--------------------------------------------
    def get_teachers_per_establishment_data(self):

        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Carrega os dados da tabela
        #-------------------
        cmd ="""SELECT      Ano,
                            Estabelecimentos.Designacao,
                            Fichas_Docencia.Cod_Docente,
                            Docentes.Nome_Completo
                FROM        Fichas_Docencia
                            INNER JOIN Estabelecimentos
                                ON Fichas_Docencia.Cod_Estabelecimento = 
                                    Estabelecimentos.Cod_Estabelecimento
                            INNER JOIN Docentes
                                ON Fichas_Docencia.Cod_Docente= 
                                    Docentes.Cod_Docente
                ORDER BY    Ano, Estabelecimentos.Designacao"""
                    
        cursor.execute(cmd)
        
        #Coloca os dados num dicionário
        #------------------
        dictData = {}
        n = 0
        for row in cursor:
            
            ano = row[0]
            estabelecimento = row[1].encode('utf-8')
            codDocente = row[2]
            nomeDocente = row[3].encode('utf-8')

            #Dicionário de docentes já inicializado para tornar o codigo menos
            #extenso.
            #-------------
            dictDocente = {}
            dictDocente[codDocente] = nomeDocente
            #-------------

            #Verifica se a chave já existe no dicionario.
            #Senão existir adiciona-a e o valor tamem.
            #------------------
            if ano not in dictData:
                dictData[ano] = {}
                dictData[ano][estabelecimento] = dictDocente

            else:
                #Verifica se o estabelecimento já existe na lista.
                #Senão existir adiciona-o e o docente também.
                #------------------
                if estabelecimento not in dictData[ano]:
                    dictData[ano][estabelecimento] = dictDocente
                else:
                    #Caso já exista um dicionário para este estabelecimento,
                    #adciciona ao dicionario dos docentes do estabelecimento.
                    dictData[ano][estabelecimento][codDocente] = nomeDocente
                pass
                    
            pass
        pass

        return dictData
        
    pass
    
    #Devolve um dicionario com os dados para a estatistica dos 
    #professores por categoria, por estabelecimento e por ano.
    #O dicionário devolvido é composto por:
    # - Um dic. com os as categorias como chave;
    # - Dentro de cada categoria um dic. com os nomes dos estabelecimentos
    #   como chave;
    # - Dentro do dic. de estabelecimentos um dic.com os anos;
    # - Dentro do dic. de ano um dic. com os cód. dos docentes
    #   como chave e o nome no valor.
    #--------------------------------------------
    def get_teachers_per_category_establishment_year_data(self):
        
        print 'A recolher os dados da BD...'
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Carrega os dados da tabela
        #-------------------
        cmd ="""SELECT      Categorias.Designacao,
                            Estabelecimentos.Designacao,
                            Ano,
                            Fichas_Docencia.Cod_Docente,
                            Docentes.Nome_Completo
                FROM        Fichas_Docencia
                            INNER JOIN Categorias
                                ON Fichas_Docencia.Cod_Categoria = 
                                    Categorias.Cod_Categoria
                            INNER JOIN Estabelecimentos
                                ON Fichas_Docencia.Cod_Estabelecimento = 
                                    Estabelecimentos.Cod_Estabelecimento
                            INNER JOIN Docentes
                                ON Fichas_Docencia.Cod_Docente= 
                                    Docentes.Cod_Docente
                ORDER BY    Categorias.Designacao, 
                            Estabelecimentos.Designacao, Ano"""
                    
        cursor.execute(cmd)
        
        #Coloca os dados num dicionário
        #------------------
        dictData = {}
        n = 0
        for row in cursor:
            
            categoria = row[0].encode('utf-8')
            estabelecimento = row[1].encode('utf-8')
            ano = row[2]
            codDocente = row[3]
            nomeDocente = row[4].encode('utf-8')

            #Dicionário de docentes já inicializado para tornar o codigo menos
            #extenso.
            #-------------
            dictDocente = {}
            dictDocente[codDocente] = nomeDocente
            #-------------

            #Verifica se a categoria já existe no dicionario.
            #Senão existir adiciona-a e os restantes valores tamem.
            #------------------
            if categoria not in dictData:
                
                dictData[categoria] = {}
                dictData[categoria][estabelecimento] = {}
                dictData[categoria][estabelecimento][ano] = dictDocente

            #Verifica se o estabelecimento já existe no dicionario.
            #Senão existir adiciona-a e os restantes valores tamem.
            #------------------
            elif estabelecimento not in dictData[categoria]:
 
                dictData[categoria][estabelecimento] = {}
                dictData[categoria][estabelecimento][ano] = dictDocente

            #Verifica se o ano já existe no dicionario.
            #Senão existir adiciona-a e os restantes valores tamem.
            elif ano not in dictData[categoria][estabelecimento]:
                    
                dictData[categoria][estabelecimento][ano] = dictDocente

              
            else:
                dictData[categoria][estabelecimento][ano]\
                    [codDocente] = nomeDocente
            pass
        pass
        
        print 'Dados da BD processados!'
        return dictData
        
    pass
    
    #Devolve um dicionario com os dados para a estatistica dos 
    #professores por tipo de grau, por estabelecimento e por ano.
    #O dicionário devolvido é composto por:
    # - Um dic. com os os tipos de grau como chave;
    # - Dentro de cada categoria um dic. com os nomes dos estabelecimentos
    #   como chave;
    # - Dentro do dic. de estabelecimentos um dic.com os anos;
    # - Dentro do dic. de ano um dic. com os cód. dos docentes
    #   como chave e o nome no valor.
    #--------------------------------------------
    def get_teachers_per_type_degree_establishment_year_data(self):
        
        print 'A recolher os dados da BD...'
        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Carrega os dados da tabela
        #-------------------
        cmd ="""SELECT      Tipos_Graus.Designacao,
                            Estabelecimentos.Designacao,
                            Ano,
                            Fichas_Docencia.Cod_Docente,
                            Docentes.Nome_Completo
                FROM        Fichas_Docencia
                            INNER JOIN Graus
                                ON Fichas_Docencia.Cod_Grau = 
                                    Graus.Cod_Grau
                            INNER JOIN Tipos_Graus
                                ON Graus.Cod_Tipo_Grau = 
                                    Tipos_Graus.Cod_Tipo_Grau
                            INNER JOIN Estabelecimentos
                                ON Fichas_Docencia.Cod_Estabelecimento = 
                                    Estabelecimentos.Cod_Estabelecimento
                            INNER JOIN Docentes
                                ON Fichas_Docencia.Cod_Docente= 
                                    Docentes.Cod_Docente
                ORDER BY    Tipos_Graus.Designacao, 
                            Estabelecimentos.Designacao, Ano"""
                    
        cursor.execute(cmd)
        
        #Coloca os dados num dicionário
        #------------------
        dictData = {}
        n = 0
        for row in cursor:
            
            tipoGrau = row[0].encode('utf-8')
            estabelecimento = row[1].encode('utf-8')
            ano = row[2]
            codDocente = row[3]
            nomeDocente = row[4].encode('utf-8')

            #Dicionário de docentes já inicializado para tornar o codigo menos
            #extenso.
            #-------------
            dictDocente = {}
            dictDocente[codDocente] = nomeDocente
            #-------------

            #Verifica se o tipo de grau já existe no dicionario.
            #Senão existir adiciona-a e os restantes valores tamem.
            #------------------
            if tipoGrau not in dictData:
                
                dictData[tipoGrau] = {}
                dictData[tipoGrau][estabelecimento] = {}
                dictData[tipoGrau][estabelecimento][ano] = dictDocente

            #Verifica se o estabelecimento já existe no dicionario.
            #Senão existir adiciona-a e os restantes valores tamem.
            #------------------
            elif estabelecimento not in dictData[tipoGrau]:
 
                dictData[tipoGrau][estabelecimento] = {}
                dictData[tipoGrau][estabelecimento][ano] = dictDocente

            #Verifica se o ano já existe no dicionario.
            #Senão existir adiciona-a e os restantes valores tamem.
            elif ano not in dictData[tipoGrau][estabelecimento]:
                    
                dictData[tipoGrau][estabelecimento][ano] = dictDocente

              
            else:
                dictData[tipoGrau][estabelecimento][ano]\
                    [codDocente] = nomeDocente
            pass
        pass
        
        print 'Dados da BD processados!'
        return dictData
        
    pass
        
    #Cria um dicionário a partir dos dados de uma tabela da BD.
    #A key do dicionario será o campo de texto.
    #--------------------------------------------
    def table_to_dict(self, tableName, fieldName1, fieldName2):

        #Abre uma ligação à BD e um cursor
        #-------------------- 
        bd = sqlite3.connect(self.DATASOURCE)
        cursor = bd.cursor()

        #Carrega os dados da tabela
        #-------------------
        cmd ="""SELECT     {0}, {1}
                FROM       {2}""".\
                    format(fieldName1, fieldName2, tableName)
                    
        cursor.execute(cmd)
        
        #Coloca os dados num dicionário
        #------------------
        dictData = {}
        
        for row in cursor:
            dictData[row[1].encode('utf-8')] = row[0]
        pass

        return dictData
    pass
    #--------------------------------------------

    #Trata as apostrofes de uma lista de strings.
    #Acrescente mais duas apostrofes de modo a não perturbar o script de SQL.
    #--------------------------------
    def clear_apostrophe(self, data):
        newData = []
        
        for str in data:
            
            tmp = str.replace("'","''")
            newData.append(tmp) 
        pass
    
        return newData
    pass